<template>
	<a-select
		class="select"
		v-model="selectedValue"
		v-bind="getProps"
		:loading="loading"
		:allowClear="!loading"
		@dropdownVisibleChange="dropdownVisibleChange"
		@change="change"
		@search="search"
		@inputKeydown="inputKeydown"
		@popupScroll="popupScroll"
	>
		<a-icon @click="clear" slot="clearIcon" type="close-circle" theme="filled" />
		<div slot="dropdownRender" slot-scope="menu">
			<v-nodes :vnodes="menu" />
			<template v-if="loadType === 'pagination'">
				<a-divider class="divider" />
				<div class="paging-box" @mousedown="e => e.preventDefault()">
					<a-pagination
						size="small"
						:current="params.pageNum"
						:pageSize="params.pageSize"
						:total="total"
						@change="paginationChange"
					/>
				</div>
			</template>
			<div v-if="loadType === 'scroll' && listData.length >= total && listData.length !== 0" class="empty">暂无更多数据</div>
		</div>
		<a-select-option
			v-for="item in listData"
			:key="item.value"
			:value="item.label"
			:option="item"
		>

			{{ item.label }}
		</a-select-option>
	</a-select>
</template>

<script>
import { getDataAPI } from './data';

/** @name 定义一些下拉框组件的默认值，为了更好的满足业务逻辑 **/
const DEFAULT_PROPS = {
	mode: 'default', // 仅支持这两种模式: default/multiple
  placeholder: '请选择',
  showArrow: false, // 不使用默认的清除按钮，使用slot插入清除按钮，更好的控制清除事件
  showSearch: false, // 是否支持输入搜索
  filterOption: false, // 不使用默认的筛选规则，因为分页行为，筛选需要传递到接口层面去过滤
  defaultActiveFirstOption: false, // 是否默认高亮第一个选项, 默认是true
  optionLabelProp: 'children' // 回填到选择框的 option 的属性值，默认是 Option 的子元素
}

export default {
	components: {
    VNodes: {
      functional: true,
      render: (_, ctx) => ctx.props.vnodes
    }
  },
	props: {
		value: {
      type: [Number, String, Array],
      default: undefined
    },
		/** @name 是否支持自定义输入的值，单选-直接输入即可，多选-需要回车操作 **/
		isCustomInput: {
			type: Boolean,
			default: false,
		},
		/** @name 加载方式，pagination/scroll **/
		loadType: {
			type: String,
			default: 'pagination'
		},
		/** @name 分页参数 **/
		pagination: {
			type: Object,
			default: () => ({})
		}
	},
	data() {
		return {
			loading: false,
			params: {
				pageNum: 1,
        pageSize: 5,
				keyword: ''
			},
			listData: [],
			total: 0,
			selectedValue: undefined,
			// 用于处理 search 事件默认最终会输出一次空的行为, 其主要会造成与用户删除的行为冲突
      open: false,
		}
	},
	computed: {
		getProps () {
      return {
        ...DEFAULT_PROPS,
        ...this.$attrs
      }
    },
	},
	watch: {
		value: {
      handler: function() {
				this.selectedValue = this.value
			},
			deep: true,
			immediate: true
    },
		selectedValue () {
      this.$emit('input', this.selectedValue)
    },
	},
	created() {
		this.params = Object.assign(this.params, this.pagination);
	},
	methods: {
		/** @name 下拉列表滚动时的回调 **/
		popupScroll({ target }) {
			if (this.loading || this.total <= this.listData.length || this.loadType !== 'scroll') return;
			const isTouchBottom = (target.scrollTop + target.offsetHeight + 10) > target.scrollHeight
      if (isTouchBottom) {
				this.params.pageNum = this.params.pageNum + 1;
				this.getData(true);
      }
		},
		/** @name 键盘按下时回调 **/
    inputKeydown ({ code, target }) {
			// 按下回车键
      if (code === 'Enter' && this.isCustomInput) {
        const inputValue = target.value;
        this.selectedValue.push(inputValue);
        this.params.keyword = '';
      }
    },
		/** @name 搜索事件 **/
		search(value) {
			if(!this.getProps.showSearch) return;
			if(this.open) {
        const inputValue = value || undefined;
				if (this.isCustomInput) {
					// 单选-自定义输入值
          if (this.getProps.mode !== 'multiple') {
            this.selectedValue = inputValue;
          }
        }
        this.params.keyword = inputValue;
        this.params.pageNum = 1;
        this.getData();
      }
		},
		/** @name 下拉框选择 **/
		change(selectedValue, options) {
			let selectedOption;
      if (Array.isArray(options)) {
        selectedOption = options.map(item => item.data.attrs.option);
      } else {
        selectedOption = options.data.attrs.option;
      }
			this.$emit('change', selectedValue, selectedOption)
		},
		/** @name 分页操作 **/
		paginationChange(page) {
			this.params.pageNum = page;
      this.getData();
		},
		/** @name 点击清除按钮 **/
    clear () {
      this.params = {
        pageNum: 1,
        pageSize: 5,
				keyword: '',
				...this.pagination
      }
			this.selectedValue = undefined;
			this.getData();
    },
		/** @name 展开下拉菜单的回调 **/
		dropdownVisibleChange(open) {
			this.open = open;
      if (open) {
				if (this.loading) return;
				if (this.listData.length !== 0 && this.params.pageNum === 1 && this.params.keyword === '') return;
				// 重置回第一页
        this.resetData();
      } else {
        if (!this.isCustomInput) {
          this.params.keyword = '';
        }
      }
		},
		/** @name 重置下拉菜单数据 **/
		resetData() {
			this.params.pageNum = 1;
			this.params.keyword = '';
			this.getData();
		},
		/** @name 获取数据 **/
    getData (isScroll) {
      this.loading = true
			getDataAPI(this.params).then(res => {
				this.listData = isScroll ? this.listData = [...this.listData, ...res.rows] : res.rows;
				this.total = res.total
				this.loading = false
			}).catch(() => {
				this.loading = false
			})
    },
	}
}
</script>

<style scoped>
.select {
	width: 100%;
}
.divider {
  margin: 2px 0;
}
.paging-box {
  display: flex;
  justify-content: flex-end;
  box-sizing: border-box;
  padding: 4px 8px 8px 0;
}
.empty {
	text-align: center;
	font-size: 13px;
	color: #666;
}
</style>
